; void pixelar_asm (
; 	unsigned char *src, RDI
; 	unsigned char *dst, RSI
; 	int m, edx
; 	int n, ecx
; 	int src_row_size, r8d
; 	int dst_row_size  r9d
; );

global pixelar_asm

pixelar_asm:
	push rbp
	mov rbp, rsp
	push rbx
	push r12
	push r13
	push r14
	push r15
	
	movsxd r8, r8d		; Expandimos con ceros a la izquierda los int
	movsxd r9, r9d
	movsxd rdx, edx
	movsxd rcx, ecx
	pxor xmm8, xmm8		; Ponemos en 0 a xmm8
	
	xor r13, r13		; Contador filas
	cicloFila:
	
		xor r12, r12	; Contador columnas
		cicloColumna:
			mov ebx, r8d				; Asigno a rbx el row_size de la img de entrada
			imul ebx, r13d				; Multiplico por la fila en que estoy
			add rbx, r12				; Sumamos la columna con la estamos trabajando
			
			movdqu xmm0, [rdi+rbx] 		; Busco en la imagen de entrada 4 filas de 16 pixeles 
			
			add ebx, r8d				; Le sumo un row_size para ir a la fila de abajo
			movdqu xmm1, [rdi+rbx]
			
			add ebx, r8d				; Le sumo un row_size para ir a la fila de abajo
			movdqu xmm2, [rdi+rbx]
			
			add ebx, r8d				; Le sumo un row_size para ir a la fila de abajo
			movdqu xmm3, [rdi+rbx]
			
			;Copiamos los pixeles obtenidos a otros 4 registros xmm
			movdqu xmm4, xmm0
			movdqu xmm5, xmm1
			movdqu xmm6, xmm2
			movdqu xmm7, xmm3
			
			;Pasamos los pixeles de la parte alta de los registros a la parte baja
			psrldq xmm4, 8
			psrldq xmm5, 8
			psrldq xmm6, 8
			psrldq xmm7, 8
			
			;Extendemos con 0 a la izquierda pasando cada pixel de 1 byte a word (para poderlos sumar)
			;Pasamos los 8 bytes menos significativos a word
			pmovzxbw xmm0, xmm0
			pmovzxbw xmm1, xmm1
			pmovzxbw xmm2, xmm2
			pmovzxbw xmm3, xmm3
			
			pmovzxbw xmm4, xmm4
			pmovzxbw xmm5, xmm5
			pmovzxbw xmm6, xmm6
			pmovzxbw xmm7, xmm7
			
			
			paddw xmm0, xmm1		;xmm0 = |s18|s17|s16|s15|s14|s13|s12|s11	(s = Suma de pixeles )
			paddw xmm2, xmm3		;xmm2 = |s28|s27|s26|s25|s24|s23|s22|s21	(s = Suma de pixeles )
			paddw xmm0, xmm2		;xmm0 = |s28+s18|s27+s17|s26+s16|s25+s15|s24+s14|s23+s13|s22+s12|s21+s11	(s = Suma de pixeles )
			movdqu xmm2, xmm0		;xmm2 = |s28+s18|s27+s17|s26+s16|s25+s15|s24+s14|s23+s13|s22+s12|s21+s11	(s = Suma de pixeles )
			psrldq xmm2, 2			;xmm2 = |0      |s28+s18|s27+s17|s26+s16|s25+s15|s24+s14|s23+s13|s22+s12	(s = Suma de pixeles )
			paddw xmm0, xmm2		;xmm0 = |x|s28+s18+s27+s17|x|s26+s16+s25+s15|x|s24+s14+s23+s13|x|s22+s12+s21+s11		
			movdqu xmm2, xmm0
			psrldq xmm2, 4			;xmm2 = |x|              x|x|s28+s18+s27+s17|x|x|x              |s24+s14+s23+s13
			paddw xmm0, xmm2		;xmm0 = |x|x|x|sumaTotal2|x|x|x|sumaTotal1
			
			movdqu xmm9, xmm0		;xmm9 = |x|x|x|sumaTotal2|x|x|x|sumaTotal1
			movdqu xmm10, xmm0		;xmm10 = |x|x|x|sumaTotal2|x|x|x|sumaTotal1
			
			pslldq xmm9, 14			;xmm9 = sumaTotal1|0|0|0|0|0|0|0
			psrldq xmm9, 14			;xmm9 = |0|0|0|0|0|0|0|sumaTotal1
			
			
			psrldq xmm10, 8			;xmm10 = |0|0|0|0|x|x|x|sumaTotal2
			pslldq xmm10, 14		;xmm10 = sumaTotal2|0|0|0|0|0|0|0|
			psrldq xmm10, 6			;xmm10 = |0|0|0|sumaTotal2|0|0|0|0
			
			paddw xmm9, xmm10		;xmm9 = |0|0|0|sumaTotal2|0|0|0|sumaTotal1
			movdqu xmm10, xmm9		;xmm10= |0|0|0|sumaTotal2|0|0|0|sumaTotal1
			pslldq xmm10, 2			;xmm10= |0|0|sumaTotal2|0|0|0|sumaTotal1|0
			paddw xmm9, xmm10		;xmm9 = |0|0|sumaTotal2|sumaTotal2|0|0|sumaTotal1|sumaTotal1
			movdqu xmm10, xmm9		;xmm10 =|0|0|sumaTotal2|sumaTotal2|0|0|sumaTotal1|sumaTotal1
			.hola:
			pslldq xmm10, 4			;xmm10 = sumaTotal2|sumaTotal2|0|0|sumaTotal1|sumaTotal1|0|0
			paddw xmm9, xmm10		;xmm9 = |sumaTotal2|sumaTotal2|sumaTotal2|sumaTotal2|sumaTotal1|sumaTotal1|sumaTotal1|sumaTotal1
			movdqu xmm0, xmm9		;xmm0 = |sumaTotal2|sumaTotal2|sumaTotal2|sumaTotal2|sumaTotal1|sumaTotal1|sumaTotal1|sumaTotal1
			
			;Hacemos lo mismo para los otros pixeles:			
			paddw xmm4, xmm5
			paddw xmm6, xmm7
			paddw xmm4, xmm6		
			movdqu xmm6, xmm4		
			psrldq xmm6, 2			
			paddw xmm4, xmm6			
			movdqu xmm6, xmm4
			psrldq xmm6, 4			
			paddw xmm4, xmm6	
			
			movdqu xmm9, xmm4		
			movdqu xmm10, xmm4		
			
			pslldq xmm9, 14			
			psrldq xmm9, 14			
			
			psrldq xmm10, 8			
			pslldq xmm10, 14		
			psrldq xmm10, 6			
			
			paddw xmm9, xmm10		
			movdqu xmm10, xmm9		
			pslldq xmm10, 2			
			paddw xmm9, xmm10		
			movdqu xmm10, xmm9		
			pslldq xmm10, 4			
			paddw xmm9, xmm10		
			movdqu xmm4, xmm9		
			
			;En xmm0 y xmm4 tengo los pixeles que quiero poner en la img. destino pero en word
			
			;Los dividos por 16
			psrlw xmm0, 4
			psrlw xmm4, 4
			
			;Pasamos los word a byte
			packuswb xmm0, xmm8		;xmm0 = 0|0|0|0|0|0|0|0|sumaTotal2|sumaTotal2|sumaTotal2|sumaTotal2|sumaTotal1|sumaTotal1|sumaTotal1|sumaTotal1|
			packuswb xmm4, xmm8		;xmm4 = 0|0|0|0|0|0|0|0|sumaTotal4|sumaTotal4|sumaTotal4|sumaTotal4|sumaTotal3|sumaTotal3|sumaTotal3|sumaTotal3|
			
			pslldq xmm4, 8			;xmm4 = sumaTotal4|sumaTotal4|sumaTotal4|sumaTotal4|sumaTotal3|sumaTotal3|sumaTotal3|sumaTotal3|0|0|0|0|0|0|0|0|
			paddb xmm0, xmm4		;xmm4 = sumaTotal4|sumaTotal4|sumaTotal4|sumaTotal4|sumaTotal3|sumaTotal3|sumaTotal3|sumaTotal3|sumaTotal2|sumaTotal2|sumaTotal2|sumaTotal2|sumaTotal1|sumaTotal1|sumaTotal1|sumaTotal1|
			
			;Ponemos los pixeles en las 4 filas de la img. destino
			mov ebx, r9d			; Asigno a rbx el row_size de la img de salida
			imul ebx, r13d			; Multiplico por la fila que estoy recorriendo
			add ebx, r12d			; Le sumo la columna en la que estamos trabajando	

			movdqu [rsi+rbx], xmm0
			
			add ebx, r9d			;Sumamos el row_size de la img de salida para ir a la fila de abajo
			movdqu [rsi+rbx], xmm0
			
			add ebx, r9d			;Sumamos el row_size de la img de salida para ir a la fila de abajo
			movdqu [rsi+rbx], xmm0
			
			add ebx, r9d			;Sumamos el row_size de la img de salida para ir a la fila de abajo
			movdqu [rsi+rbx], xmm0
			
			;Avanzamos de a 16 por columna
			add r12, 16 ; avanzamos a las proximas 16 columnas
			cmp r12d, ecx
			je avanzarFila
			
      lea r10, [r12+4]   ;Nos fijamos si faltan menos de 4 columnas por recorrer, en tal caso no las usamos y avanzamos a la proxima fila
			cmp r10d, ecx
			jg avanzarFila
      cuantoAtrasColumna: ; No quedan menos de 4 columnas por recorrer
			lea r10, [r12+16]
			cmp r10d, ecx			;Si es menor o igual nos quedan por lo menos 16 columnas por copiar
			jle cicloColumna
			sub r12, 4
			jmp cuantoAtrasColumna	;Con el ciclo calculamos cuanto tenemos que ir para atras para agarrar justo 16
			
						
			avanzarFila:
			add r13, 4		;Avanzamos 4 filas
			cmp r13d, edx	;Vemos si es igual al alto de la imagen
			je fin
			;si es menor r13d a edx:
			lea r10, [r13+4]
			cmp r10d, edx	;Si es menor quedan por lo menos 4 filas por copiar
			jle cicloFila
			;Si es mayor es que quedan menos de 4 filas por copiar, salimos del programa
			
			
			;cuantoAtrasFila:
			;lea r10, [r13+4]
			;cmp r10d, edx	;Si es menor o igual nos quedan por lo menos 4 filas por copiar
			;je cicloFila
			;sub r13, 1
			;jmp cuantoAtrasFila
			
	fin:	
	pop r15
	pop r14
	pop r13
	pop r12
	pop rbx
	pop rbp
	ret
